package org.bravof.analysis;

import lombok.extern.log4j.Log4j2;
import org.bravof.common.Constants;
import org.bravof.common.FileTypeEnum;
import org.bravof.common.PropertyUtil;
import org.bravof.generate.DTOGenerator;
import org.bravof.generate.MapperGenerator;
import org.bravof.generate.POGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 数据处理
 */
@Log4j2
@Component
public class DataProcessor {
    @Autowired
    private PropertyUtil propertyUtil;

    @Autowired
    private POGenerator poGenerator;

    @Autowired
    private DTOGenerator dtoGenerator;

    @Autowired
    private MapperGenerator mapperGenerator;

    public void generatorDataMap() {
        try {
            FileReader fileReader = new FileReader(new File(propertyUtil.getSourceFileAbsolutePath()));
            BufferedReader bufferedReader = new BufferedReader(fileReader);
            List<Map<String, String>> javaMapList = new ArrayList<>();
            List<Map<String, String>> xmlMapList = new ArrayList<>();
            String eachLine;
            while(true) {
                eachLine = bufferedReader.readLine();
                //读到空行，终止程序
                if(StringUtils.isEmpty(eachLine)) break;
                //存储成员变量原名称，及其变量类型
                Map<String, String> fieldAndJavaType = new LinkedHashMap<>();
                //存储成员变量原名称，及其映射文件类型
                Map<String, String> fieldAndMapperType = new LinkedHashMap<>();
                //处理读取的数据，删除下划线，并且将下划线后面的一个字符转为大写
                String[] fieldArray = eachLine.trim().split(Constants.COLON);

                //如果指定了Java数据类型
                if(fieldArray.length == 2) {
                    //原生数据库字段类型
                    String sqlType = fieldArray[1];
                    //从配置类获取数据库字段的Java数据类型映射
                    String javaTypeStr = Constants.mySQLTypeMap.get(sqlType);
                    fieldAndJavaType.put(fieldArray[0], javaTypeStr);

                    fieldAndMapperType.put(fieldArray[0], sqlType);
                } else {
                    //如果未指定数据类型，Java默认设为String
                    fieldAndJavaType.put(fieldArray[0], Constants.STRING);
                    //如果未指定数据类型，数据库默认设为VARCHAR
                    fieldAndMapperType.put(fieldArray[0], Constants.VARCHAR);
                }


                javaMapList.add(fieldAndJavaType);
                xmlMapList.add(fieldAndMapperType);
            }
            System.out.println("\r");
            log.info("配置文件配置项列表");
            log.info("---------------->>>>>>");
            log.info("源数据文件路径 -> {}", propertyUtil.getSourceFileAbsolutePath());
            log.info("文件生成目录 -> {}", propertyUtil.getOutPutFilePath());
            log.info("文件包名前缀 -> {}", propertyUtil.getPackNamePrefix());
            log.info("所需要生成的文件类型 -> {}", propertyUtil.getOptionalFileType());
            log.info("原始类名称 -> {}", propertyUtil.getClassName());
            log.info("DTO和PO中需要导入的包名(全名称) -> {}", propertyUtil.getImportListStr());
            log.info("DTO和PO中需要添加的类注解 -> {}", propertyUtil.getAnnotationListStr());
            log.info("DTO和PO中需要实现的接口 -> {}", propertyUtil.getImplementListStr());
            log.info("----------------<<<<<<");
            System.out.println("\r");
            log.info("解析成员变量名称及其数据类型键值对列表完毕，变量列表如下");
            log.info("---------------->>>>>>");
            log.info("javaMapList = {}", javaMapList);
            log.info("javaMapList = {}", javaMapList);
            log.info("----------------<<<<<<");
            System.out.println("\r");

            //判断是否生成DTO
            if(propertyUtil.getOptionalFileType().contains(FileTypeEnum.DTO.name())) {
                dtoGenerator.setResourceMapList(javaMapList);
                Thread thread = new Thread(dtoGenerator);
                log.info("生成 {} 线程启动...", FileTypeEnum.DTO.name());
                thread.start();
            }

            //判断是否生成PO
            if(propertyUtil.getOptionalFileType().contains(FileTypeEnum.PO.name())) {
                poGenerator.setResourceMapList(javaMapList);
                Thread thread = new Thread(poGenerator);
                log.info("生成 {} 线程启动...", FileTypeEnum.PO.name());
                thread.start();
            }

            //判断是否生成Mapper
            if(propertyUtil.getOptionalFileType().contains(FileTypeEnum.Mapper.name())) {
                Thread thread = new Thread(mapperGenerator);
                log.info("生成 {} 线程启动...", FileTypeEnum.Mapper.name());
                thread.start();
            }


        } catch(FileNotFoundException e) {
            log.error("文件 {} 不存在", propertyUtil.getSourceFileAbsolutePath());
            log.error("请确认文件路径后重试，程序终止");
            System.exit(-1);
        } catch(IOException e) {
            log.error(e.getMessage(), e);
            System.exit(-1);
        }
    }
}
